/**
 * docx.js库 - 用于生成Word文档
 * 基于docx.js库实现的Word文档生成工具
 */

// 确保全局docx对象可用
if (typeof docx === 'undefined') {
  throw new Error('无法找到全局docx对象，请确保正确引入了docx-global.js');
}

class DocxGenerator {
  /**
   * 创建新的Word文档
   * @returns {Object} 文档对象
   */
  static createDocument() {
    // 仅定义样式，暂不创建节，所有要插入的元素先缓存
    const document = new docx.Document({
      // 提前传入一个空的 sections 数组，避免新版本 docx 在迭代 sections 时抛错
      sections: [],
      styles: {
        paragraphStyles: [
          {
            id: "tableTitle",
            name: "Table Title",
            basedOn: "Normal",
            next: "Normal",
            run: {
              size: 28,
              bold: true
            },
            paragraph: {
              spacing: {
                after: 200,
                before: 200
              },
              alignment: docx.AlignmentType.CENTER
            }
          },
          {
            id: "tableCaption",
            name: "Table Caption",
            basedOn: "Normal",
            next: "Normal",
            run: {
              size: 24
            },
            paragraph: {
              alignment: docx.AlignmentType.CENTER,
              spacing: {
                before: 100,
                after: 300
              }
            }
          }
        ]
      }
    });

    // 初始化缓存数组，用于临时存放所有待加入的元素
    document._generatorContent = [];
    return document;
  }
  
  /**
   * 添加表格到文档
   * @param {Object} doc - 文档对象
   * @param {Array} headers - 表头数组
   * @param {Array} rows - 数据行数组
   * @param {Object} options - 表格选项
   * @returns {Object} 更新后的文档对象
   */
  static addTable(doc, headers, rows, options = {}) {
    // 表号与表标题
    const tableNo = options.tableNo !== undefined ? options.tableNo : undefined;
    // 若提供了表注释，优先作为表名显示；否则退回至建表名
    const displayName = options.tableComment || options.tableName || '表结构';

    // 生成表格下方的标题，如"表1-用户角色关联表"
    const captionText = tableNo !== undefined
      ? `表${tableNo}-${displayName}`
      : displayName;

    // 创建表格上方的表名段落（仅显示"用户角色关联表"或表名本身）
    const titleParagraph = new docx.Paragraph({
      text: displayName,
      style: "tableTitle"
    });

    // 创建表格下方的标题段落
    const captionParagraph = new docx.Paragraph({
      text: captionText,
      style: "tableCaption"
    });
    
    // 创建表头行
    const headerRow = new docx.TableRow({
      tableHeader: true,
      children: headers.map(header => {
        return new docx.TableCell({
          children: [new docx.Paragraph({ text: header, alignment: docx.AlignmentType.CENTER })],
          verticalAlign: docx.VerticalAlign.CENTER,
          borders: {
            bottom: {
              style: docx.BorderStyle.SINGLE,
              size: 4,
              color: "000000"
            }
          }
        });
      })
    });
    
    // 创建数据行
    const dataRows = rows.map((rowData, rowIndex) => {
      const isLastRow = rowIndex === rows.length - 1;
      
      return new docx.TableRow({
        children: rowData.map(cellText => {
          return new docx.TableCell({
            children: [new docx.Paragraph({ text: cellText || '', alignment: docx.AlignmentType.CENTER })],
            verticalAlign: docx.VerticalAlign.CENTER,
            borders: {
              top: { style: docx.BorderStyle.NONE },
              bottom: isLastRow ? { style: docx.BorderStyle.SINGLE, size: 10, color: "000000" } : { style: docx.BorderStyle.NONE },
              left: { style: docx.BorderStyle.NONE },
              right: { style: docx.BorderStyle.NONE }
            }
          });
        })
      });
    });
    
    // 创建表格
    const table = new docx.Table({
      width: {
        size: 100,
        type: docx.WidthType.PERCENTAGE
      },
      rows: [headerRow, ...dataRows],
      borders: {
        top: {
          style: docx.BorderStyle.SINGLE,
          size: 10,
          color: "000000"
        },
        bottom: {
          style: docx.BorderStyle.SINGLE, 
          size: 10,
          color: "000000"
        },
        left: { style: docx.BorderStyle.NONE },
        right: { style: docx.BorderStyle.NONE },
        insideHorizontal: { style: docx.BorderStyle.NONE },
        insideVertical: { style: docx.BorderStyle.NONE }
      }
    });
    
    // 根据选项决定是否应用三线表样式（默认沿用现有边框即可）
    if (options.threeLineStyle) {
      // 三线表样式已在创建单元格时直接应用
    }
    
    // 存储所有要添加到文档的内容，保持顺序：表名 -> 表格 -> 标题
    const docElements = [titleParagraph, table, captionParagraph];
    
    // 添加约束信息（如果有的话）
    if (options.constraints && options.constraints.length > 0) {
      // 添加一个空白行
      docElements.push(new docx.Paragraph(""));
      
      // 主键信息
      const primaryKeys = options.constraints.filter(c => c.type === 'PRIMARY KEY');
      if (primaryKeys.length > 0) {
        docElements.push(new docx.Paragraph({
          text: "主键信息:",
          bold: true
        }));
        
        primaryKeys.forEach(pk => {
          docElements.push(new docx.Paragraph({
            text: `• 主键: (${pk.columns.join(', ')})`,
            indent: { left: 360 } // 0.25 inch indent
          }));
        });
      }
      
      // 索引信息
      const indexes = options.constraints.filter(c => c.type === 'INDEX' || c.type === 'UNIQUE');
      if (indexes.length > 0) {
        docElements.push(new docx.Paragraph({
          text: "索引信息:",
          bold: true
        }));
        
        indexes.forEach(idx => {
          const idxType = idx.type === 'UNIQUE' ? '唯一索引' : '普通索引';
          docElements.push(new docx.Paragraph({
            text: `• ${idxType} ${idx.name || ''}: (${idx.columns.join(', ')})`,
            indent: { left: 360 }
          }));
        });
      }
      
      // 外键信息
      const foreignKeys = options.constraints.filter(c => c.type === 'FOREIGN KEY');
      if (foreignKeys.length > 0) {
        docElements.push(new docx.Paragraph({
          text: "外键信息:",
          bold: true
        }));
        
        foreignKeys.forEach(fk => {
          let fkText = `• 外键 ${fk.name || ''}: (${fk.columns.join(', ')}) 引用 ${fk.refTable}(${fk.refColumns.join(', ')})`;
          
          if (fk.onDelete) {
            fkText += ` ON DELETE ${fk.onDelete}`;
          }
          
          if (fk.onUpdate) {
            fkText += ` ON UPDATE ${fk.onUpdate}`;
          }
          
          docElements.push(new docx.Paragraph({
            text: fkText,
            indent: { left: 360 }
          }));
        });
      }
    }
    
    // 使用在 createDocument 中缓存的 content 数组
    const children = doc._generatorContent || (doc._generatorContent = []);

    // 如果已经有内容，先插入 3 个空段落以控制间距
    if (children && children.length > 0) {
      for (let i = 0; i < 3; i++) {
        children.push(new docx.Paragraph(""));
      }
    }

    // 追加当前表格及附加信息
    docElements.forEach(el => children.push(el));
    
    return doc;
  }
  
  /**
   * 保存文档为.docx文件
   * @param {Object} doc - 文档对象
   * @param {string} filename - 文件名
   * @returns {Promise<Blob>} 文档Blob对象
   */
  static saveDocument(doc, filename) {
    // 若尚未真正把内容写入节，这里一次性写入
    if (doc._generatorContent && doc._generatorContent.length > 0) {
      doc.addSection({
        children: doc._generatorContent,
        // 此处可以设置页边距、页面方向等属性
      });
      
      // 清空缓存
      doc._generatorContent = [];
    }
    
    // 创建Packer实例并保存文档
    return docx.Packer.toBlob(doc).then(blob => {
      // 在浏览器中下载文件
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement("a");
      document.body.appendChild(a);
      a.style = "display: none";
      a.href = url;
      a.download = filename;
      a.click();
      window.URL.revokeObjectURL(url);
      return blob;
    });
  }
  
  /**
   * 应用三线表样式
   * @param {Object} table - 表格对象
   */
  static applyThreeLineStyle(table) {
    // 遍历行和单元格，设置边框
    table.rows.forEach((row, rowIndex) => {
      const isFirstRow = rowIndex === 0;
      const isLastRow = rowIndex === table.rows.length - 1;
      
      row.children.forEach(cell => {
        // 表头的底边框和表格的底边框要特殊处理（加粗）
        if (isFirstRow) {
          cell.borders.bottom = {
            style: docx.BorderStyle.SINGLE,
            size: 8,
            color: "000000"
          };
        }
        
        if (isLastRow) {
          cell.borders.bottom = {
            style: docx.BorderStyle.SINGLE,
            size: 8,
            color: "000000"
          };
        }
      });
    });
  }
} 